package com.satyam.smooth.dao.testUtil;

import com.satyam.smooth.hibernateutils.HibernateSessionUtils;
import com.satyam.smooth.util.LoggerFactory;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.jpa.HibernateEntityManager;

/**
 *
 * @author satyam
 */
public class GenericTestHelper {

    private static final Logger log = LoggerFactory.make();
    private final ThreadLocal<Session> tls = new ThreadLocal<>();
    private final ThreadLocal<Boolean> doCommit = new ThreadLocal<>();
    private volatile String persistenceUnitName = null;
    private volatile HibernateEntityManager emf = null;

    public GenericTestHelper(String persistenceUnitName) {
        this.persistenceUnitName = persistenceUnitName;
    }

    private void openSession() {
       /* if (emf == null) {
            try {
                emf = Persistence.createEntityManagerFactory(persistenceUnitName);
            } catch (Exception ex) {
                throw new RuntimeException("Problem in creating an EntityManagerFactory instance " + ex.getMessage(), ex);
            }
        }*/

        Session session = tls.get();
        if (session == null) {
            //session = emf.createEntityManager().unwrap(Session.class);
            session = HibernateSessionUtils.getSessionFactory().openSession();
            tls.set(session);
        }
    }

    private void closeSession() {
        Session session = tls.get();
        tls.set(null);
        if (session != null && session.isOpen()) {
            session.close();
        }
    }

    public Session getCurrentSession() {
        return tls.get();
    }

    public void beginTransaction() {
        try {
            doCommit.set(true);
            openSession();
            Session session = getCurrentSession();
            session.beginTransaction();
            log.debug("Transaction began");
        } catch (RuntimeException ex) {
            log.error("begingTransaction failed!");
            throw ex;
        }
    }

    public void commitTransaction() {
        Session session = getCurrentSession();
        try {
            if (doCommit.get()) {
                session.getTransaction().commit();
                log.debug("Transaction comitted");
            } else {
                session.getTransaction().rollback();
                log.debug("Transaction rollbacked");
            }
        } catch (RuntimeException ex) {
            try {
                session.getTransaction().rollback();
            } catch (Exception e) {

            }
            log.error("Transaction rollback failed!");
            throw ex;
        } finally {
            closeSession();
        }
    }

    public void setRollbackTransaction(){
        doCommit.set(false);
    }
}
